package com.business.user.utils;

import com.auth0.jwt.JWTSigner;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.internal.com.fasterxml.jackson.databind.ObjectMapper;
import com.business.common.enums.BusinessExceptionEnum;
import com.business.common.enums.ErrorEnum;
import com.business.common.exception.BusinessException;
import com.business.common.exception.CustomException;
import com.business.common.utils.SystemClock;
import com.business.user.entity.UserDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class JWTUtil {

    private static Logger logger = LoggerFactory.getLogger(JWTUtil.class);

    private final static String SECRET = "chenjiehong....";

    private static final String EXP = "exp";

    private static final String PAYLOAD = "payload";

    /**
     * 用户登录成功后生成Jwt
     * 使用Hs256算法  私匙使用用户密码
     *
     * @param ttlMillis jwt过期时间 秒
     * @param user      登录成功的user对象
     * @return
     */
    public static String createJWT(Long ttlMillis, UserDto user) throws IOException {
        final JWTSigner signer = new JWTSigner(SECRET);
        final Map<String, Object> claims = new HashMap<String, Object>();
        ObjectMapper mapper = new ObjectMapper();
        String jsonString = mapper.writeValueAsString(user);
        claims.put(PAYLOAD, jsonString);
        if(ttlMillis != null){
            claims.put(EXP, System.currentTimeMillis() + ttlMillis *1000);
        }
        return signer.sign(claims);

    }


    /**
     * Token的解密
     *
     * @param token 加密后的token
     * @return
     */
    public static UserDto parseJWT(String token) throws Exception {

        final JWTVerifier verifier = new JWTVerifier(SECRET);
        try {
            final Map<String, Object> claims = verifier.verify(token);

            if (claims.containsKey(EXP)) {
                long exp = (Long) claims.get(EXP);
                long currentTimeMillis = SystemClock.now();
                if (exp < currentTimeMillis) {
                    throw new BusinessException(BusinessExceptionEnum.USER_LOGIN_OVERTIME);
                }
            }
            if ( claims.containsKey(PAYLOAD)) {
                String json = (String) claims.get(PAYLOAD);
                ObjectMapper objectMapper = new ObjectMapper();
                return objectMapper.readValue(json, UserDto.class);
            }
        }catch (Exception e){
            logger.error("jwt校验错误" + verifier,e);
            throw new CustomException(ErrorEnum.AUTH_ERROR);
        }
        return  null;

    }

}
